import typeOfUtils from '../../../utils/type-of-utils'
import RenderUtils from '../RenderUtils'
import {FormItemConfig, RenderTypeItem} from "../ConfigType";
import {DynamicForm} from "../index.vue.d";
// @ts-ignore
import {CreateElement} from "vue/types/vue";

const cascader: RenderTypeItem = {
  slotNames: ['empty'],
  scopedSlotsNames: ['default'],
  name: 'cascader',
  /**
   * 初始化自己的绑定值
   * @param vm
   * @param formItem
   */
  initFormValue(vm:DynamicForm, formItem:FormItemConfig) {
    vm.$set(vm.formData, formItem.prop, [])
  },
  /**
   * @param vm
   * @param formItem
   */
  initFormItem(vm:DynamicForm, formItem:FormItemConfig)  {
    if (typeOfUtils.isEmpty(formItem.props.options)) {
      vm.$set(formItem.props, 'options', [])
    }
    if (typeOfUtils.isFunction(formItem.props.asyncSetOptions)) {
      vm.$set(formItem.props, 'loading', true)
      formItem.props.asyncSetOptions().then(res => {
        vm.$set(formItem.props, 'options', res)
      }).finally(() => {
        formItem.props.loading = false
      })
    }
  },
  /**
   * 异步加载
   * @param formItem
   * @param vm
   * @param query
   */
  asyncSetOptions(formItem:FormItemConfig, vm:DynamicForm, query) {
    if (typeOfUtils.isFunction(formItem.props.asyncSetOptions)) {
      formItem.props.loading = true
      formItem.props.asyncSetOptions(query).then(res => {
        vm.$set(formItem.props, 'options', res)
      }).finally(() => {
        formItem.props.loading = false
      })
    }
  },
  /**
   *
   * @param createElement
   * @param vm
   * @param formItem
   * @return {VNode[]}
   */
  render(createElement:CreateElement, vm:DynamicForm, formItem:FormItemConfig) {
    let tag = 'el-cascader'
    let options = formItem.props.options || []
    if (typeOfUtils.isEmpty(options) && typeOfUtils.isFunction(formItem.props.setOptions)) {
      options = formItem.props.setOptions() || []
    }
    const config = RenderUtils.getConfig(vm,formItem,{
      props: {
        placeholder: '请选择',
        options
      },
      on: {
        ...formItem.events,
        change: (val) => {
          if (typeOfUtils.isFunction(formItem.events?.change)) {
            formItem.events.change(options, val)
          }
          vm.$emit('selectChange', formItem.prop, vm.formData, {type: this.name, options})
        },
        focus: (e) => {
          if (typeOfUtils.isFunction(formItem.events?.focus)) {
            formItem.events.focus(options, e)
          }
          if (typeOfUtils.isFunction(formItem.props.focusLoadAgain)) {
            if (formItem.props.focusLoadAgain()) {
              this.asyncSetOptions(formItem, vm)
            }
          }
        }
      },
      directives: [
        {
          name: 'loading',
          value: formItem.props?.loading || false
        }
      ]
    },this)
    config.scopedSlots = RenderUtils.renderScopedSlots(formItem, createElement, this.scopedSlotsNames, vm)
    const children = RenderUtils.renderSlotsChildren(formItem, createElement, this.slotNames, vm)
    return [
      createElement(tag, config, children)
    ]
  }
}

export default cascader
